package com.yklx.youke.service;

import com.yklx.youke.entity.*;
import com.yklx.youke.repository.BookingRepository;
import com.yklx.youke.repository.SessionRepository;
import com.yklx.youke.repository.TeacherRepository;
import com.yklx.youke.repository.StudentRepository;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

@Service
public class BookingService {

    private final BookingRepository bookingRepository;
    private final SessionRepository sessionRepository;
    private final TeacherRepository teacherRepository;
    private final StudentRepository studentRepository;
    private final YoubiTransactionService youbiTransactionService;

    public BookingService(BookingRepository bookingRepository, SessionRepository sessionRepository, 
                         TeacherRepository teacherRepository, StudentRepository studentRepository,
                         YoubiTransactionService youbiTransactionService) {
        this.bookingRepository = bookingRepository;
        this.sessionRepository = sessionRepository;
        this.teacherRepository = teacherRepository;
        this.studentRepository = studentRepository;
        this.youbiTransactionService = youbiTransactionService;
    }

    public List<Map<String, Object>> getUserBookings(String status, String dateRange, Boolean past) {
        // In a real implementation, this would query the database based on the current user's role
        // and return appropriate bookings
        return List.of(); // Placeholder
    }

    public Map<String, Object> getBookingDetails(UUID bookingId) {
        Booking booking = bookingRepository.findById(bookingId)
                .orElseThrow(() -> new IllegalArgumentException("Booking not found: " + bookingId));

        return Map.of(
            "booking", booking,
            "session", booking.getSession(),
            "participants", List.of(booking.getSession().getTeacher(), booking.getSession().getStudent())
        );
    }

    public Map<String, Object> createBooking(UUID teacherId, UUID childId, String subject, String scheduledTimeStr, Integer duration) {
        Teacher teacher = teacherRepository.findById(teacherId)
                .orElseThrow(() -> new IllegalArgumentException("Teacher not found: " + teacherId));

        Student student = studentRepository.findById(childId)
                .orElseThrow(() -> new IllegalArgumentException("Student not found: " + childId));

        // Create session
        LocalDateTime scheduledTime = LocalDateTime.parse(scheduledTimeStr);
        Session session = new Session(teacher, student, subject, scheduledTime);
        session.setDuration(duration);
        Session savedSession = sessionRepository.save(session);

        // Create booking
        BigDecimal amount = teacher.getHourlyRate().multiply(BigDecimal.valueOf(duration / 60.0)); // Calculate cost
        Booking booking = new Booking(savedSession, student.getParent(), amount);
        Booking savedBooking = bookingRepository.save(booking);

        return Map.of(
            "booking", savedBooking,
            "session", savedSession,
            "paymentRequired", true
        );
    }

    public Map<String, Object> confirmBooking(UUID bookingId) {
        Booking booking = bookingRepository.findById(bookingId)
                .orElseThrow(() -> new IllegalArgumentException("Booking not found: " + bookingId));

        // Update booking status to confirmed
        booking.setStatus(Booking.BookingStatus.CONFIRMED);
        booking.setPaymentStatus(Booking.PaymentStatus.PAID);
        Booking updatedBooking = bookingRepository.save(booking);

        // In a real implementation, process payment here

        return Map.of(
            "booking", updatedBooking,
            "paymentProcessed", true
        );
    }

    public Map<String, Object> cancelBooking(UUID bookingId) {
        Booking booking = bookingRepository.findById(bookingId)
                .orElseThrow(() -> new IllegalArgumentException("Booking not found: " + bookingId));

        // Update booking status to cancelled
        booking.setStatus(Booking.BookingStatus.CANCELLED);
        Booking updatedBooking = bookingRepository.save(booking);

        // Process refund if applicable
        BigDecimal refundAmount = calculateRefund(booking);
        if (refundAmount.compareTo(BigDecimal.ZERO) > 0) {
            // In a real implementation, process refund here
            youbiTransactionService.processRefund(booking, refundAmount);
        }

        return Map.of(
            "booking", updatedBooking,
            "refundAmount", refundAmount
        );
    }

    private BigDecimal calculateRefund(Booking booking) {
        // Implement refund calculation logic based on cancellation policy
        // For now, returning the original amount for demo purposes
        if (booking.getSession().getScheduledTime().isAfter(LocalDateTime.now().plusHours(24))) {
            // Full refund if cancelled more than 24h in advance
            return booking.getAmount();
        } else if (booking.getSession().getScheduledTime().isAfter(LocalDateTime.now().plusHours(1))) {
            // 50% refund if cancelled within 24h but more than 1h in advance
            return booking.getAmount().divide(BigDecimal.valueOf(2));
        } else {
            // No refund if cancelled within 1h of session
            return BigDecimal.ZERO;
        }
    }
    
    /**
     * 获取所有预约（管理端）
     * @param status 预约状态
     * @param dateRange 日期范围
     * @param includePast 是否包含过去的预约
     * @return 预约列表
     */
    public List<Map<String, Object>> getAllBookings(String status, String dateRange, Boolean includePast) {
        // 管理端获取所有预约的逻辑
        // 在实际实现中，这里会查询数据库并返回所有预约记录
        return List.of(); // Placeholder
    }
}